package 蚂蚁课堂;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;

/**
 * 比如：t1线程和t2线程使用Exchange通讯，那么当t1给t2传递一个数据的时候，t2接收到的数据是同一个堆内存中的地址
 * 也就是说t1发出的数据，和t2接收到的数据是同一个对象。那么就有可能造成线程不安全
 * 如：t1发送一个list过去，t2接收list
 *    同时t1线程做list.add()操作，t1线程做list.remove()操作，这就存在线程不安全
 */
public class ExchangerDemo3 {

    private static List<Integer> list= new ArrayList<Integer>(Arrays.asList(1,2,3));


    private static Exchanger<List<Integer>> exchanger=new Exchanger<>();
    public static void main(String[] args) {

            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        List<Integer> exchange = exchanger.exchange(list);
                        TimeUnit.SECONDS.sleep(2);
                        /**
                         * 打印出：[1, 2, 3, 111]，要知道111这个数据是我在t2线程中加的，那么在t1线程就能得到
                         * 说明t1和t2线程中的消息，都指向同一个对内存地址
                         */
                        System.out.println(exchange);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    List<Integer> exchange = exchanger.exchange(list);
                    /**
                     * 当t1和t2交换数据的时候，将t2线程接收的信息再add(111)，观察t1线程的System.out.println(exchange);
                     */
                    exchange.add(111);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }
}
